/***************************************************************
|	File:		GameplayState.cpp
|	Author:     John Gawne
|	Course:		Structure of Game Desing
|	Purpose:	GameplayState class initializes & runs the game logic
***************************************************************/

#include "GameplayState.h"
#include "Game.h"
#include "MainMenuState.h"

//For saving
#include <ShlObj.h>


#include <iostream>
using namespace std;
#include "../SGD Wrappers/SGD_AudioManager.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_String.h"

#include "../SGD Wrappers/SGD_EventManager.h"
#include "../SGD Wrappers/SGD_Event.h"
#include "../SGD Wrappers/SGD_MessageManager.h"
#include "../SGD Wrappers/SGD_Message.h"
#include "MessageID.h"
#include "TileSystem.h"
#include "BitmapFont.h"
#include "Bomb.h"
#include "Player.h"
#include "ParticleSystem.h"
#include "StaticObject.h"
#include "ObjectManager.h"
#include "GrappleHook.h"
#include "Explosion.h"
#include "Crosshair.h"
#include "Camera.h"
#include "Crate.h"
#include <cstdlib>
#include <cassert>
#include <time.h>
#include <math.h>

#include <iostream>
#include <string>
#include <stdio.h>

#include <fstream>

//states
#include "MainMenuState.h"
#include "CustomState.h"

#include <algorithm>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

std::wstring s2ws(const std::string& s);
HWND window;

/**************************************************************/
// GetInstance
//	- allocate static global instance
//	- return THE instance
/*static*/ GameplayState* GameplayState::GetInstance(void)
{
	static GameplayState s_Instance;	// stored in global memory once
	return &s_Instance;
}

/**************************************************************/
// Enter
//	- reset game
//	- load resources
//	- set up entities
/*virtual*/ void GameplayState::Enter(void)
{
	window = GetActiveWindow();
	font = Game::GetInstance()->GetFont();
	// Initialize the Event Manager
	m_pEvents = SGD::EventManager::GetInstance();
	m_pEvents->Initialize();

	// Initialize the Message Manager
	m_pMessages = SGD::MessageManager::GetInstance();
	m_pMessages->Initialize(&MessageProc);

	SGD::GraphicsManager*	pGraphics = SGD::GraphicsManager::GetInstance();
	SGD::AudioManager*		pAudio = SGD::AudioManager::GetInstance();

	m_fScreenWidth = (float)Game::GetInstance()->GetScreenWidth();
	m_fScreenHeight = (float)Game::GetInstance()->GetScreenHeight();


	m_hPlayer = pGraphics->LoadTexture(L"resource/graphics/ScientistRunning.png");
	m_hCrosshair = pGraphics->LoadTexture(L"resource/graphics/JAG_Crosshair.png");
	m_hFrame = pGraphics->LoadTexture(L"resource/graphics/Large_Frame_Purple.png");

	m_pPlayer = CreatePlayer();
	m_pCamera = new Camera(m_pPlayer);
	Game::GetInstance()->SetCamera(m_pCamera);

	m_pObjectManager = new ObjectManager();

	m_pCrosshair = CreateCrosshair();

	//m_pCrate = CreateCrate(400, 300);
	//CreateGrappleGun();
	//CreateGrappleHook();
	m_bTimer = true;

	explosion = new Explosion;
	explosion->SetSize({ 100, 600 });
	explosion->SetPosition({ -400, 0 });

	m_bPause = false;
	m_bVictory = false;

	// Set background color
	SGD::GraphicsManager::GetInstance()->SetClearColor({ 0, 0, 0 });	// black

	m_fWorldTimer = 45.f;
	m_fTrackTimer = 0.f;


	std::fstream file;
	file.open("resource/menu/Pause.mnu", std::ios_base::in);
	if (file.is_open())
	{
		file >> m_nNumItems;
		file.ignore(INT_MAX, '\n');
		for (unsigned char i = 0; i < m_nNumItems; i++)
		{
			char szTemp[100];
			file.getline(&szTemp[0], 100, '\n');

			SGD::String strItem;
			for (unsigned char i = 0; i < 100; i++)
			{
				strItem += szTemp[i];
				if (szTemp[i] == '\0')
				{
					strItem += szTemp[i];
					break;
				}
			}
			m_szItems.push_back(strItem);
		}
	}
	file.close();

	// Add Menu Options to map
	for (unsigned int i = 0; i < m_szItems.size(); i++)
		m_mSelectedItem[i] = m_szItems.at(i).c_str();

	MainMenuState* menu = MainMenuState::GetInstance();

	if (menu->GetSelectedItem().at(menu->GetNumCursor()) == L"New Game")
	{
		m_pObjectManager->GetTileSystem()->Load("resource/graphics/TutorialNewGame.bin", m_pObjectManager);
		m_bInTutorial = true;
	}
	
	if (menu->GetSelectedItem().at(menu->GetNumCursor()) == L"Load Save")
	{
		m_pObjectManager->GetTileSystem()->Load("resource/graphics/World143.bin", m_pObjectManager);
		m_pPlayer->SetChecks(Game::GetInstance()->GetSave()->Upgrades[Game::GetInstance()->GetSave()->SavedSlot]);
			m_bInTutorial = false;
	}

	if (menu->GetSelectedItem().at(menu->GetNumCursor()) == L"Tutorial")
		m_pObjectManager->GetTileSystem()->Load("resource/graphics/Tutorial.bin", m_pObjectManager);

	if (menu->GetSelectedItem().at(menu->GetNumCursor()) == L"Custom Map")
		m_pObjectManager->GetTileSystem()->Load(CustomState::GetInstance()->GetMapName(), m_pObjectManager);

	m_pPlayer->SetPosition(m_ptPlayerPosition);
	m_pPlayer->SetImageSize({ 90, 136 });
	m_pCamera->SetPosition(m_pPlayer->GetPosition());

	m_hBackgroundMusic = pAudio->LoadAudio("resource/audio/Background.xwm");
	pAudio->PlayAudio(m_hBackgroundMusic, true);

}

//	test.Load("test.txt");}


/**************************************************************/
// Exit
//	- deallocate entities
//	- unload resources
/*virtual*/ void GameplayState::Exit(void)
{

	m_bMainMenu = false;

	m_pObjectManager->RemoveAll();
	delete explosion;
	delete m_pObjectManager;
	//m_pObjectManager->UnLoadAll();
	//delete m_pObjectManager;



	SGD::GraphicsManager*	pGraphics = SGD::GraphicsManager::GetInstance();
	SGD::AudioManager*		pAudio = SGD::AudioManager::GetInstance();

	pAudio->UnloadAudio(m_hBackgroundMusic);

	//pGraphics->UnloadTexture(m_hBackgroundImage);
	//pGraphics->UnloadTexture(m_hPlayer);
	pGraphics->UnloadTexture(m_hCrosshair);
	pGraphics->UnloadTexture(m_hFrame);
	pAudio->UnloadAudio(m_hBackgroundMusic);

	m_pPlayer->GetGrapGun()->KillGrappleHook();

	delete m_pPlayer;
	delete m_pCrosshair;
	delete m_pCamera;

	// Terminate & deallocate the SGD wrappers
	m_pEvents->Terminate();
	m_pEvents = nullptr;
	SGD::EventManager::DeleteInstance();

	m_pMessages->Terminate();
	m_pMessages = nullptr;
	SGD::MessageManager::DeleteInstance();
}


/**************************************************************/
// Input
//	- handle user input
/*virtual*/ bool GameplayState::Input(void)
{
	SGD::InputManager* pInput = SGD::InputManager::GetInstance();

	if (pInput->IsKeyPressed(SGD::Key::Escape) == true
		|| pInput->IsButtonPressed(0, 6))
	{
		if (m_bPause)
			m_nPauseCursor = 0;

		if (!m_bSave)
			m_bPause = !m_bPause;
		else
			m_bSave = false;
	}

	if (m_bPause == false)
	{
		if (pInput->IsKeyPressed(SGD::Key::P) == true)
		{
			m_pObjectManager->Respawn(0);
			m_pPlayer->SetPosition(m_ptPlayerPosition);
		}

		//if (pInput->IsKeyPressed(SGD::Key::Q) == true)
		//	return false;

		if (pInput->IsKeyPressed(SGD::Key::M))
			Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
	}

	if (pInput->IsKeyPressed(SGD::Key::Escape) == true 
		&& m_bVictory == true)
	{
		Game::Save* save = Game::GetInstance()->GetSave();
		save->Score.sort([](float one, float two) -> bool {
			return one < two;
		});

		if (save->Score.size() && save->Score.size() > 4)
		{
			float last = save->Score.back();

			if (m_fTrackTimer < last)
			{
				save->Score.push_back(m_fTrackTimer);
				save->Score.sort([](float one, float two) -> bool {
					return one < two;
				});
			}
		}
		else
			save->Score.push_back(m_fTrackTimer);

		if (save->Score.size() >5)
			save->Score.pop_back();

		Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
	}

	if (GetActiveWindow() != window)
		m_bPause = true;

	if (m_bPause == true)
		if (!PauseInput(pInput))
			return false;
	
	//if (!pInput->IsAnyKeyDown())
	//{
	//	m_pCamera->SetMoving(false);
	//}

	return true;	// keep playing
}


/**************************************************************/
// Update
//	- update game entities
/*virtual*/ void GameplayState::Update(float elapsedTime)
{
	m_fControlTimer += elapsedTime;

	SGD::InputManager* pInput = SGD::InputManager::GetInstance();
	
	if (m_bPause == false && m_bVictory == false)
	{
		m_pPlayer->Update(elapsedTime);
		m_pObjectManager->UpdateAll(elapsedTime);

		m_pCamera->Update(elapsedTime);
		SetCameraX(m_pCamera->GetCameraX());
		SetCameraY(m_pCamera->GetCameraY());

		m_pObjectManager->CheckCollisions(m_pPlayer);
		
		if (dynamic_cast<Player*>(m_pPlayer)->GetGrapGun()->GetGrappleHook() != nullptr)
			m_pObjectManager->CheckCollisions((dynamic_cast<Player*>(m_pPlayer)->GetGrapGun()->GetGrappleHook()));
			m_pCrosshair->Update(elapsedTime);
		m_pMessages->Update();
		m_pEvents->Update();
		if (m_bTimer)
		m_fWorldTimer -= elapsedTime;
		m_fTrackTimer += elapsedTime;

		if (m_fWorldTimer <= 0.0f && !m_bInTutorial)
		{
			if (explosion != nullptr)
			{
				explosion->Update(elapsedTime);
				m_pObjectManager->CheckCollisions(explosion);
			}
			m_pPlayer->GetParticle(1)->Update(elapsedTime);
			m_pCamera->CameraShake();
			SetCameraX(m_pCamera->GetCameraX());
			SetCameraY(m_pCamera->GetCameraY());
		}

		if (m_cPortal & (1 << PortalMainMenu))
		{
			m_cPortal = 0;
			Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
		}
		else if (m_cPortal & (1 << PortalNext))
		{
			m_cPortal = 0;
			m_pObjectManager->RemoveAll();
			delete m_pObjectManager;
			m_pObjectManager = new ObjectManager;
			m_pObjectManager->GetTileSystem()->Load("resource/graphics/World143.bin", m_pObjectManager);
			m_pPlayer->SetPosition(m_ptPlayerPosition);
			m_bInTutorial = false;
			SGD::MessageManager::GetInstance()->QueueMessage(new SGD::Message(MessageID::MSG_PLAYER_DIED));
		}

	}
}


/**************************************************************/
// Render
//	- render the game entities
/*virtual*/ void GameplayState::Render(void)
{
	m_pObjectManager->RenderAll();
	m_pPlayer->Render();

	if (m_fWorldTimer <= 0.0f)
		m_pPlayer->GetParticle(1)->Render();

	if (!SGD::InputManager::GetInstance()->IsControllerConnected(0))
		m_pCrosshair->Render();
	if (explosion != nullptr)
		explosion->Render();

	SGD::String BombTimer;
	BombTimer = to_wstring(m_fWorldTimer);

	int tempint = BombTimer.find_last_of(L".");
	BombTimer.erase(BombTimer.begin() + tempint + 3, BombTimer.end());

	SGD::String TrackTime;
	TrackTime = to_wstring(m_fTrackTimer);

	int Trackint = TrackTime.find_last_of(L".");
	TrackTime.erase(TrackTime.begin() + Trackint + 3, TrackTime.end());

	if (m_fWorldTimer <= 0)
	{
		BombTimer = L"0.00";
		//Game::GetInstance()->GetFont()->Draw(&BombTimer, 100, (int)m_fScreenHeight - 32, 1.0f, {});

		if (explosion != nullptr)
		if (m_pPlayer->GetRect().IsIntersecting(explosion->GetRect()))
		{
			explosion->HandleCollision(m_pPlayer);
			m_bExplode = false;
		}
	}
		//Game::GetInstance()->GetFont()->Draw(&BombTimer, 100, (int)m_fScreenHeight - 32, 1.0f, {});

	if (m_bPause == true)
		Pause();

	if (m_bVictory == true)
	{
		SGD::String win;
		win = L"YOU WON!";
		Game::GetInstance()->GetFont()->Draw(&win, (int)(m_fScreenWidth / 2 - 12 * 1.5f * 6), (int)m_fScreenHeight / 3, 1.5f, SGD::Color(255, 0, 0));

		SGD::String TimeItTook;
		TimeItTook = L"and     it     only     took     you ";
		Game::GetInstance()->GetFont()->Draw(&TimeItTook, (int)(m_fScreenWidth / 2 - 22 * 1.5f * 6), (int)m_fScreenHeight / 3 + 50, 1.5f, SGD::Color(255, 0, 0));
		Game::GetInstance()->GetFont()->Draw(&TrackTime, (int)(m_fScreenWidth / 2 - 12 * 1.5f * 6), (int)m_fScreenHeight / 3 + 100, 1.5f, SGD::Color(255, 0, 0));
		SGD::String secs;
		secs = L"seconds";
		Game::GetInstance()->GetFont()->Draw(&secs, (int)(m_fScreenWidth / 2 + 12 * 1.5f * 6), (int)m_fScreenHeight / 3 + 100, 1.5f, SGD::Color(255, 0, 0));

		SGD::String tomenu;
		tomenu = L"Press esc to go to main menu";
		Game::GetInstance()->GetFont()->Draw(&tomenu, (int)(m_fScreenWidth / 2 - 32 * 1.5f * 6), (int)m_fScreenHeight / 3 + 200, 1.0f, SGD::Color(255, 0, 0));
	}
}


/**************************************************************/
// MessageProc
//	- process messages queued in the MessageManager
//	- STATIC METHOD
//		- does NOT have invoking object!!!
//		- must use singleton to access members
/*static*/ void GameplayState::MessageProc(const SGD::Message* pMsg)
{
	/* Show warning when a Message ID enumerator is not handled */
#pragma warning( push )
#pragma warning( 1 : 4061 )

	// What type of message?
	switch (pMsg->GetMessageID())
	{
		case MessageID::MSG_UNKNOWN:
		default:
			OutputDebugStringW(L"Game::MessageProc - unknown message id\n");
			break;
		case MessageID::MSG_PLAYER_DIED:
		{
			GameplayState::GetInstance()->m_pPlayer->SetPosition(GameplayState::GetInstance()->m_ptPlayerPosition);
			GameplayState::GetInstance()->m_pPlayer->Reset();
			GameplayState::GetInstance()->m_pObjectManager->Respawn(0);
			if(GameplayState::GetInstance()->explosion != nullptr)
				GameplayState::GetInstance()->m_fWorldTimer = 45.f;
			else
			{					
				GameplayState::GetInstance()->explosion = new Explosion;
				GameplayState::GetInstance()->explosion->SetSize({ 100, 600 });
				GameplayState::GetInstance()->explosion->SetPosition({ -400, 0 });
			}
			GameplayState::GetInstance()->explosion->Reset();
			GameplayState::GetInstance()->explosion->SetSize({ 100, 600 });
			GameplayState::GetInstance()->explosion->SetPosition({ -400, 0 });
			GameplayState::GetInstance()->m_bTimer = true;
			SGD::EventManager::GetInstance()->QueueEvent(new SGD::Event("GateRaise"));

			break;
		}
		case MessageID::MSG_RESETBOMB:
		{
			delete GameplayState::GetInstance()->explosion;
			GameplayState::GetInstance()->explosion = nullptr;
			break;
		}								 
										 
	}


	/* Restore previous warning levels */
#pragma warning( pop )

}

Player* GameplayState::CreatePlayer(void) const
{
	Player* newPlayer = new Player;

	Game* game = Game::GetInstance();
	Game::Save* save = game->GetSave();

	newPlayer->SetImage(m_hPlayer);
	newPlayer->SetSize({ 64, 128 });

	//newPlayer->SetPosition(m_ptPlayerPosition);// *save.PlayerPos[save.SavedSlot]);//({ 100,300 });
	//ParticleSystem ps;
	//ps.Load("resource//savefiles//PlayerSliding.xml", ps, *newPlayer);
	//newPlayer->SetParticle(ps);

	return newPlayer;

}
//Crate* GameplayState::CreateCrate(float Startx, float Starty) //<- might need a starting point to be placed on map
//{
//
//	Crate * crate = new Crate;
//
//	crate->SetImage(m_hCrate);
//	crate->SetSize({128, 128});
//
//	crate->SetPosition({Startx, Starty});
//	
//	return crate;
//}


Crosshair* GameplayState::CreateCrosshair(void)
{
	Crosshair* newCrosshair = new Crosshair;

	newCrosshair->SetImage(m_hCrosshair);
	newCrosshair->SetSize({ 167, 167 });

	return newCrosshair;

}
void GameplayState::CreateGrappleGun(void) const
{
	//StaticObject * gun  = new GrappleGun;
	//gun->SetImage(SGD::GraphicsManager::GetInstance()->LoadTexture(L"resource/graphics/GrappleGunText.png"));
	//gun->SetSize({ 128, 32 });
	//gun->SetPosition({ 800, 200 });
	//gun->SetObjectType(ObjectType::UPGRADE);
	//dynamic_cast<GrappleGun*>(gun)->SetActive(false);
	//m_pObjectManager->AddObject(gun, 3);
}

void	GameplayState::CreateGrappleHook(void) const
{

}
SGD::Point GameplayState::GetPlayerPos() const { return m_pPlayer->GetPosition(); }

std::wstring s2ws(const std::string& s)
{
	int len;
	int slength = (int)s.length() + 1;
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
	wchar_t* buf = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
	std::wstring r(buf);
	delete[] buf;
	return r;
}

void GameplayState::Pause()
{
	SGD::GraphicsManager::GetInstance()->DrawTexture(m_hFrame, { (m_fScreenWidth / 2)-256, (m_fScreenHeight / 2)-256 });

	if (!m_bSave)
		for (unsigned int i = 0; i < m_nNumItems; i++)
		{
			if (m_nPauseCursor == i)
				font->Draw(&m_szItems[i], (int)(m_fScreenWidth / 1.5f) - 32 * 7, ((int)m_fScreenHeight / 3 + 50) + i * 40, 1, SGD::Color(255, 255, 0));
			else
				font->Draw(&m_szItems[i], (int)(m_fScreenWidth / 1.5f) - 32 * 8, ((int)m_fScreenHeight / 3 + 50) + i * 40, 0.75f, SGD::Color());
		}
	else
		for (unsigned int i = 0; i < 3; i++)
		{
			if (m_nPauseCursor == i)
				font->Draw(Game::GetInstance()->GetSave()->Time[i], 32 * 6, ((int)m_fScreenHeight / 3 + 50) + i * 40, 0.55f, SGD::Color(255, 255, 0));
			else
				font->Draw(Game::GetInstance()->GetSave()->Time[i], 32 * 7, ((int)m_fScreenHeight / 3 + 50) + i * 40, 0.40f, SGD::Color());
		}
}

bool GameplayState::PauseInput(SGD::InputManager* pInput)
{

	SGD::Vector vcontroller;


	if (m_fControlTimer > 0.2f)
	{
		vcontroller = pInput->GetLeftJoystick(0);
		m_fControlTimer = 0.f;
	}

	if (pInput->IsKeyPressed(SGD::Key::Down) == true 
		|| pInput->IsKeyPressed(SGD::Key::S) == true
		|| vcontroller.y > 0.1f)
	{
		++m_nPauseCursor;

		if (m_bSave)
		{
			if (m_nPauseCursor > 2)
				m_nPauseCursor = 0;
		}
		else if(m_nPauseCursor > (int)m_nNumItems-1)
			m_nPauseCursor = 0;
	}
	else if (pInput->IsKeyPressed(SGD::Key::Up) == true 
			|| pInput->IsKeyPressed(SGD::Key::W) == true
			|| vcontroller.y < -0.1f)
	{
		--m_nPauseCursor;

		if (m_nPauseCursor < 0)
			if (!m_bSave)
				m_nPauseCursor = m_nNumItems-1;
			else
				m_nPauseCursor = 2;
	}

	if (pInput->IsKeyPressed(SGD::Key::Enter) == true
		|| pInput->IsButtonPressed(0, 0))
	{
		if(!m_bSave)
		{
			if (m_mSelectedItem[m_nPauseCursor] == L"Resume")
				m_bPause = false;
			if (m_mSelectedItem[m_nPauseCursor] == L"Save")
			{
				m_nPauseCursor = 0;
				m_bSave = true;
			}
			if (m_mSelectedItem[m_nPauseCursor] == L"Main Menu")
				Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
			if (m_mSelectedItem[m_nPauseCursor] == L"Quit to Windows")
				return false;
		}
		else
		{
			Game::GetInstance()->GetSave()->SavedSlot = m_nPauseCursor;
			Save();
		}
	}

	return true;
}

void GameplayState::Save()
{
	// For Save file
	Game* game = Game::GetInstance();
	HRESULT hr;
	ostringstream stringstream;
	char path[MAX_PATH];
	LPWSTR wszPath = NULL;
	size_t   size;

	// Get the path to the app data folder
	hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, 0, &wszPath);

	// Convert from LPWSTR to char[]
	wcstombs_s(&size, path, MAX_PATH, wszPath, MAX_PATH);

	// Convert char types
	if (hr == S_OK)
		stringstream << path;
	string pathtowrite = stringstream.str();

	string compName = "Tesseract";
	string gameName = "TimeToRun";

	// Add the company and game information
	pathtowrite += "\\" + compName + "\\" + gameName + "\\";

	std::wstring tempwString = s2ws(pathtowrite);
	LPCWSTR result = tempwString.c_str();

	// Create our directory
	SHCreateDirectoryEx(NULL, result, 0);

	// Create our save file
	pathtowrite += "SaveSlots.sav";
	fstream file;

	Game::Save* save = Game::GetInstance()->GetSave();
		save->Upgrades[save->SavedSlot] = m_pPlayer->GetChecks();

	file.open(pathtowrite, ios_base::binary | ios_base::out);
	{
		// write out which save slot we are on
		file.write((char*)&save->SavedSlot, sizeof(save->SavedSlot));

		// loop through all 3 save slots
		for (unsigned char i = 0; i < 3; i++)
		{
			if (i == save->SavedSlot)
			{
				unsigned char upgrades = m_pPlayer->GetChecks();
				// write out player upgrades
				file.write((char*)&upgrades, sizeof(upgrades));
			}
			else
				file.write((char*)&save->Upgrades[i], sizeof(unsigned char));

			// write out time
			if (i == save->SavedSlot)
			{

				int parse = save->Time[i]->find_first_of(L' ');

				save->Time[i]->erase(save->Time[i]->begin() + parse + 2, save->Time[i]->end());


				time_t now = time(0);
				tm tstruct;
				char buf[100];

				localtime_s(&tstruct, &now);

				strftime(buf, sizeof(buf), /*"%Y-%m*/"%d.%X", &tstruct);

				*save->Time[i] += L" ";
				unsigned char count = 0;
				while (true)
				{
					if (buf[count] == '\0')
						break;
					*save->Time[i] += wchar_t(buf[count]);

					count++;
				}

				*save->Time[i] += L" Upgrades: ";

				if (save->Upgrades[i] & (1 << 2))
					*save->Time[i] += L"3";
				else if (save->Upgrades[i] & (1 << 1))
					*save->Time[i] += L"2";
				else if(save->Upgrades[i] & (1 << 0))
					*save->Time[i] += L"1";
				else if(save->Upgrades[i] == 0)
					*save->Time[i] += L"0";
				
				

			}
			unsigned int strlength = save->Time[i]->size();
			file.write((char*)&strlength, sizeof(unsigned int));
			std::string t;

			for (unsigned char j = 0; j < strlength; j++)
			{
				t += (char)save->Time[i]->at(j);
			}

			file.write((char*)t.c_str(), strlength);
		}

		// Save out options
		file.write((char*)&save->FullScreen, sizeof(save->FullScreen));
		file.write((char*)&save->MusicVolume, sizeof(save->MusicVolume));
		file.write((char*)&save->SFXVolume, sizeof(save->SFXVolume));

		// Save out Scores
		save->ScoreSize = save->Score.size();
		file.write((char*)&save->ScoreSize, sizeof(save->ScoreSize));
		for each (float score in save->Score)
			file.write((char*)&score, sizeof(score));
	}
	file.close();
}